import json
from wt.auto_test_case.dict_datamanager_mothod import DictDataManagerMethod
from loguru import logger

class DatabaseCase():
    def __init__(self):
        super().__init__()
        self.dict_db_method = DictDataManagerMethod()
        self.db_managers = self.dict_db_method.get_db_manager_method()
        self.file_manager = self.dict_db_method.get_file_manager_method()
        # sql执行
        self.dict_db_exec = self.dict_db_method.get_db_exec_method()

        # table dml执行
        self.table_dml_generators = self.dict_db_method.get_table_dml_method()
        # table del执行
        self.table_deleted_generators = self.dict_db_method.get_table_deleted_method()
        # table update执行
        self.update_table_data = self.dict_db_method.update_table_data_method()
        self.get_table_10_line = self.dict_db_method.get_table_10_line()
        local_param = self.dict_db_method.get_local_param()
        self.create_db_data = local_param["create_db_data"]
        self.db_api = local_param["db_api"]
        self.until = local_param["until"]
        # table create执行
        self.ddl_generators, self.dict_db_method, self.file_upload = self.dict_db_method.get_db_create_method()

    def get_test_data(self, type='create_info'):
        """
        get_test_data(create_info) 表示获取获取 create_datasource_data 下面的 create_info，
        get_test_data(db_info) 表示获取获取 create_datasource_data 下面的 db_info，
        :param type:
        :return:
        """
        tmp = self.create_db_data
        db_create_json = {}
        db_base_json = {}
        filter_table_json = {}
        for key, value in tmp.items():
            datasource_name = value["create_info"]['datasourceName']
            plugin_name = value["create_info"]['pluginName']
            db_info = value["db_info"]
            filter_table_name = value["filter_table_name"]
            db_create_json[datasource_name] = plugin_name
            db_base_json[datasource_name] = db_info
            filter_table_json[datasource_name] = filter_table_name
        if type == 'create_info':
            return db_create_json
        elif type == 'db_info':
            return db_base_json
        elif type == 'filter_table_name':
            return filter_table_json
        else:
            print("请确认获取数据库 create_info or db_info")

    def del_database_case(self, db_type, input_db_name=None):
        """
        删除数据库用例
        :return:
        """
        tmp = self.create_db_data
        if input_db_name is not None:
            tmp[db_type]["create_info"]["datasourceName"] = input_db_name
        print(input_db_name)
        datasourceName = tmp[db_type]['create_info']['datasourceName']
        databaseId = self.query_database_case(db_type, datasourceName)
        res = self.db_api.delete_datasource(datasourceName, databaseId)
        return res

    def create_database_case(self, db_type, input_db_name=None):
        """
        创建数据
        :param db_type: JDBC-Mysql
        :param input_db_name: 数据库名称，例：test123
        :return:
        """
        tmp = self.create_db_data
        init_datasource_name = tmp[db_type]["create_info"]["datasourceName"]
        if input_db_name is not None:
            tmp[db_type]["create_info"]["datasourceName"] = input_db_name
        db_name = tmp[db_type]["create_info"]["datasourceName"]
        create_info = tmp[db_type]["create_info"]
        res = self.db_api.create_datasource(db_type, db_name, create_info)
        # 这里必须将原始值替换回去，否则先传入input_db_name，后面就不能使用默认datasource_name了
        tmp[db_type]["create_info"]["datasourceName"] = init_datasource_name
        return res

    def connect_database_case(self, db_type, input_db_name=None):
        """
        链接数据库用例
        :return:
        """
        tmp = self.create_db_data
        if input_db_name is not None:
            tmp[db_type]["create_info"]["datasourceName"] = input_db_name
        datasourceName = tmp[db_type]['create_info']['datasourceName']
        res = self.db_api.connect_datasource(db_type, datasourceName)
        return res

    def get_database_table_case(self, db_type, input_db_name=None):
        """
        获取数据表用例
        :return:
        """
        tmp = self.create_db_data

        datasourceName = tmp[db_type]['create_info']['datasourceName']
        if input_db_name is not None:
            datasourceName = input_db_name

        databaseName = tmp[db_type]['db_info']
        res = self.db_api.get_datasource_table_info(db_type, datasourceName, databaseName, '')
        return res

    def exec_ssh_command(self, ip, user, passwd, command):
        exec_res = self.until.exec_ssh_command(ip, user, passwd, command)
        print(exec_res)
        return exec_res

    def query_database_case(self, db_type, input_db_name=None):
        """
        查询数据库用例
        :return:
        """
        tmp = self.create_db_data
        if input_db_name is not None:
            tmp[db_type]["create_info"]["datasourceName"] = input_db_name
        datasourceName = tmp[db_type]['create_info']['datasourceName']
        pluginName = tmp[db_type]["create_info"]["pluginName"]
        res = self.db_api.get_datasource_info(pluginName, datasourceName, "id")
        return res

    def change_json(self):

        data = {}
        with open(self.create_datasource_json, "r") as f:
            data["create_datasource_data"] = json.load(f)
        tem = data["create_datasource_data"]

        # 构建 json_B
        json_B = {}
        for key, value in tem.items():
            json_B[key] = {
                "create_info": value,
                "db_info": "qa_source"
            }

        # 将 json_B 转换为 JSON 格式并打印输出
        print(json.dumps(json_B, indent=2))

    def find_dot_value(self, input_str, db_type):
        db_table_list = input_str.split("@")

        if len(db_table_list) == 3:
            databaseName, schemaName, tableName = db_table_list[0], db_table_list[1], db_table_list[2]
            return databaseName, schemaName, tableName
        elif len(db_table_list) == 2:
            databaseName, tableName = db_table_list[0], db_table_list[1]
            return databaseName, tableName
        else:
            return None, None, None

    def exec_sql_with_logging(self, databaseName, tableName, ddl_sql, db_type, response_data, fun_type,
                              schemaName=None, batch_mode=0):
        exec_func = self.dict_db_exec.get(db_type)
        if not exec_func:
            response_data.update({'message': "fail", 'data': f"不支持的数据源类型 {db_type}"})
            return response_data

        # 执行SQL
        if batch_mode == 1:
            sql_template, values_list = ddl_sql
            sql_state = exec_func(db=databaseName, sql_str=sql_template, values=values_list, execute_type="batch")
        else:
            sql_state = exec_func(databaseName, ddl_sql)

        print(sql_state)

        # 表cdc模式处理
        cdc_state = "无需开启CDC"
        if db_type[-3:] == "CDC" and db_type not in ["MySQL-CDC", "Informix-CDC"]:
            if schemaName is None:
                cdc_state = self.db_managers[db_type].cdc_set_on(databaseName, tableName)
            else:
                cdc_state = self.db_managers[db_type].cdc_set_on(databaseName, schemaName, tableName)

        # 返回res转json
        response_data.update({'message': sql_state["message"], 'data': sql_state["data"], 'cdc_state': cdc_state})
        return response_data

    def db_create_case(self, db_type, table, text_type=None):
        response_data = {'message': '', 'data': []}
        db_table_list = table.split("@")
        if db_type in self.db_managers:
            if len(db_table_list) == 2:
                databaseName, tableName = self.find_dot_value(table, db_type)
                ddl_sql = self.ddl_generators[db_type](databaseName, tableName)
                schemaName = None

            elif len(db_table_list) == 3:
                databaseName, schemaName, tableName = self.find_dot_value(table, db_type)
                ddl_sql = self.ddl_generators[db_type](databaseName, schemaName, tableName)

            response_data = self.exec_sql_with_logging(databaseName=databaseName, schemaName=schemaName,
                                                           tableName=tableName, ddl_sql=ddl_sql, db_type=db_type,
                                                           response_data=response_data, fun_type="create")

        elif db_type in self.file_manager:
            if text_type is None:
                response_data.update({'message': "fail", 'data': "缺少参数:text_type"})
                return response_data
            if self.file_manager[db_type](table, text_type):
                if db_type == "LocalFile":
                    response_data.update({'message': "Success", 'data': f"{db_type}: 创建并上传成功 {table}"})
                elif self.file_upload[db_type](table, text_type):
                    response_data.update({'message': "Success", 'data': f"{db_type}: 创建并上传成功 {table}"})
                else:
                    response_data.update({'message': "fail", 'data': f"上传失败，请检查数据源模板 {db_type}"})
            else:
                response_data.update({'message': "fail", 'data': f"创建失败，请检查数据源模板和文件类型 {db_type}"})
        else:
            response_data.update({'message': "fail", 'data': f"未找到该数据源或该数据源不支持：{db_type}"})

        return response_data

    def exec_customer_sql(self, db_type, table, sql):
        before_dot, after_dot = self.find_dot_value(table, db_type)

        if db_type in self.db_managers:
            db_manager = self.db_managers[db_type]
            res = db_manager.exec_customer_sql(before_dot, sql)
            return res

    def db_delete_case(self, db_type, table, text_type=None):
        response_data = {'message': '', 'data': []}
        db_table_list = table.split("@")

        if db_type in self.db_managers:
            db_manager = self.db_managers[db_type]
            delete_state = None

            if len(db_table_list) == 2:
                databaseName, tableName = self.find_dot_value(table, db_type)
                delete_state = db_manager.execute_drop_table(databaseName, tableName)
            elif len(db_table_list) == 3:
                databaseName, schemaName, tableName = self.find_dot_value(table, db_type)
                delete_state = db_manager.execute_drop_table(databaseName, schemaName, tableName)
                print("ssss {}".format(delete_state))

            return delete_state

        elif db_type in self.file_manager:
            file_manager = self.file_manager[db_type]
            if file_manager.clear_folder(table):
                if db_type == "LocalFile":
                    response_data.update({'message': "Success", 'data': f"{db_type}: 删除成功 {table} 相关全部文件"})
                elif file_manager.clear_server_folder(table, text_type):
                    response_data.update({'message': "Success", 'data': f"{db_type}: 删除成功 {table} 相关全部文件"})
                else:
                    response_data.update({'message': "fail", 'data': f"删除服务文件失败，请检查数据源模板 {db_type}"})
            else:
                response_data.update({'message': "fail", 'data': f"删除本地文件失败，请检查数据源模板 {db_type}"})
        else:
            response_data.update({'message': "fail", 'data': f"未找到该数据源或该数据源不支持：{db_type}"})

        return response_data

    def db_select_count_case(self, db_type, table, text_type=None):
        response_data = {'message': '', 'data': []}
        db_table_list = table.split("@")

        if db_type in self.db_managers:
            db_manager = self.db_managers[db_type]

            db_select_count_state = None
            if len(db_table_list) == 2:
                databaseName, tableName = self.find_dot_value(table, db_type)
                db_select_count_state = db_manager.get_count(databaseName, tableName)
            elif len(db_table_list) == 3:
                databaseName, schemaName, tableName = self.find_dot_value(table, db_type)
                db_select_count_state = db_manager.get_count(databaseName, schemaName, tableName)

            if db_select_count_state is not None:
                response_data.update({'message': "Success", 'data': db_select_count_state})
            else:
                response_data.update({'message': "fail", 'data': f"查询失败，请检查数据源模板 {db_type}"})
        elif db_type in self.file_manager:
            file_manager = self.file_manager[db_type]
            if db_type == "LocalFile":
                line_count = file_manager.get_file_count(table)
                response_data.update({'message': "Success", 'data': line_count})
            elif file_manager.download_latest_file(table):
                line_count = file_manager.get_file_count(table)
            if file_manager.download_latest_file(table, text_type):
                line_count = file_manager.get_file_count(table, text_type)
                response_data.update({'message': "Success", 'data': line_count})
            else:
                response_data.update({'message': "fail", 'data': f"文件下载失败请检查 {db_type}"})
        else:
            response_data.update({'message': "fail", 'data': f"未找到该数据源或该数据源不支持：{db_type}"})

        return response_data

    def db_oracle_make(self, db, table, num):
        num = self.oracle11g_manager.create_and_insert_sql(db, table, num)
        return num

    def db_create_data_case(self, db_type, table, num):
        response_data = {'message': '', 'data': []}
        db_table_list = table.split("@")

        if db_type in self.db_managers:
            batch_mode = 0
            if len(db_table_list) == 2:
                databaseName, tableName = self.find_dot_value(table, db_type)
                ddl_sql = self.table_dml_generators[db_type](databaseName, tableName, num)
                # oracle/dameng 批量插入
                if db_type in ["JDBC-Oracle11g", "Oracle11g-CDC", "Dameng-CDC"]:
                    batch_mode = 1
                schemaName=None
            elif len(db_table_list) == 3:
                databaseName, schemaName, tableName = self.find_dot_value(table, db_type)
                ddl_sql = self.table_dml_generators[db_type](databaseName, schemaName, tableName, num)
            response_data = self.exec_sql_with_logging(databaseName=databaseName, schemaName=schemaName,
                                                           tableName=tableName, ddl_sql=ddl_sql, db_type=db_type,
                                                           response_data=response_data, fun_type="create_data", batch_mode=batch_mode)
        elif db_type in self.file_manager:
            response_data.update({'message': "fail", 'data': "文件类型不需要该方法"})
        else:
            response_data.update({'message': "fail", 'data': f"未找到该数据源或该数据源不支持：{db_type}"})

        return response_data

    def db_deleted_data_case(self, db_type, table):
        response_data = {'message': '', 'data': []}
        db_table_list = table.split("@")


        if db_type in self.db_managers:
            delete_state = None
            if len(db_table_list) == 2:
                databaseName, tableName = self.find_dot_value(table, db_type)
                delete_state = self.table_deleted_generators[db_type](databaseName, tableName)
            elif len(db_table_list) == 3:
                databaseName, schemaName, tableName = self.find_dot_value(table, db_type)
                delete_state = self.table_deleted_generators[db_type](databaseName, schemaName, tableName)

            if delete_state:
                response_data.update({'message': "Success", 'data': "删除成功"})
            else:
                response_data.update({'message': "fail", 'data': "删除失败,请检查模板"})

        return response_data

    def db_update_data_case(self, db_type, table):
        response_data = {'message': '', 'data': []}
        db_table_list = table.split("@")

        if db_type in self.db_managers:
            update_state = None
            if len(db_table_list) == 2:
                databaseName, tableName = self.find_dot_value(table, db_type)
                update_state = self.update_table_data[db_type](databaseName, tableName)
            elif len(db_table_list) == 3:
                databaseName, schemaName, tableName = self.find_dot_value(table, db_type)
                update_state = self.update_table_data[db_type](databaseName, schemaName, tableName)
            logger.info("更新的状态是：{}".format(update_state))

            if update_state:
                response_data.update({'message': "Success", 'data': "修改成功"})
            else:
                response_data.update({'message': "fail", 'data': "修改失败,请检查模板"})

        return response_data

    def get_db_data_case(self, db_type, table):
        response_data = {'message': '', 'data': []}
        db_table_list = table.split("@")

        if db_type in self.db_managers:
            get_db_data_state = None
            if len(db_table_list) == 2:
                databaseName, tableName = self.find_dot_value(table, db_type)
                get_db_data_state = self.get_table_10_line[db_type](databaseName, tableName)
            elif len(db_table_list) == 3:
                databaseName, schemaName, tableName = self.find_dot_value(table, db_type)
                get_db_data_state = self.get_table_10_line[db_type](databaseName, schemaName, tableName)

            if get_db_data_state:
                response_data.update({'message': "Success", 'data': get_db_data_state})
            else:
                response_data.update({'message': "fail", 'data': f"查询失败,请检查模板 {db_type}"})

        return response_data


if __name__ == '__main__':
    m = DatabaseCase()
    count = m.db_select_count_case("Doris_v1", "test.test")
    print(count)
